import pathlib
from threading import Thread
from cv2 import VideoCapture, CAP_DSHOW, cvtColor, COLOR_BGR2RGB, destroyAllWindows
from PIL import Image, ImageTk
from tkinter import Tk, Label, messagebox
from tkinter.ttk import Progressbar

folder = pathlib.Path(__file__).parent.resolve()


class Main:
    root = None
    video = None
    progressbar = None
    label = None
    show = False
    width_default = 250
    height_default = 40

    def __init__(self):
        # 创建一个TK界面
        self.root = Tk()
        self.root.resizable(False, False)
        self.root.title('技术羊出品 && 博客：jishuyang.com')
        self.root.iconbitmap(f'{folder}/logo.ico')
        self.set_width_height(self.width_default, self.height_default)
        # 进度条
        self.progressbar = Progressbar(self.root, length=220, mode="indeterminate")
        self.progressbar.grid(row=0, column=0, padx=10, pady=10, columnspan=2, sticky="NWS")
        self.progressbar.start()
        # 开启新线程防止ui卡死
        Thread(target=self.connect).start()
        self.root.mainloop()

    def connect(self):
        self.root.config(cursor="watch")
        self.root.update_idletasks()
        self.video = VideoCapture(0, CAP_DSHOW)
        if self.video.isOpened():

            self.progressbar.stop()
            self.progressbar.grid_forget()
            self.show = True

            # 宽度（单位：像素）
            width = int(self.video.get(3))
            # 高度（单位：像素）
            height = int(self.video.get(4))

            self.set_width_height(width, height)

            # 创建label标签
            self.label = Label(self.root, compound='center', text=' ', width=width, height=height)
            self.label.place(x=0, y=0, width=width, height=height)
            self.show_cam()
        else:
            messagebox.showerror("提示", " 摄像头连接失败")
            self.progressbar.stop()
            self.progressbar.grid_forget()
            self.set_width_height(self.width_default, self.height_default)
        self.root.config(cursor="arrow")

    def show_cam(self):
        res, img = self.video.read()
        if res:
            # 将array转化为image
            image_rgb = cvtColor(img, COLOR_BGR2RGB)
            img = Image.fromarray(image_rgb)
            # 显示图片到label
            image = ImageTk.PhotoImage(img)
            self.label.image = image
            self.label['image'] = image

        if self.show:
            # 创建一个定时器，每10ms进入一次函数
            self.root.after(30, self.show_cam)

    def clear(self):
        # 释放video资源
        if self.video is not None:
            self.video.release()
            destroyAllWindows()

    def set_width_height(self, width, height):
        # 窗口居中，获取屏幕尺寸以计算布局参数，使窗口居屏幕中央
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        x = (screen_width - width) / 2
        y = (screen_height - height) / 5
        self.root.geometry('%dx%d+%d+%d' % (width, height, x, y))


if __name__ == '__main__':
    main = Main()
    main.clear()
    destroyAllWindows()
